package com.atguigu.gulimall.ware.service.impl;

import com.atguigu.common.constant.WareConstant;
import com.atguigu.common.exception.GulimallEnum;
import com.atguigu.common.exception.GulimallException;
import com.atguigu.gulimall.ware.entity.PurChaseDetailFinish;
import com.atguigu.gulimall.ware.entity.PurchaseDetailEntity;
import com.atguigu.gulimall.ware.entity.WareSkuEntity;
import com.atguigu.gulimall.ware.service.PurchaseDetailService;
import com.atguigu.gulimall.ware.service.WareSkuService;
import com.atguigu.gulimall.ware.vo.PuchaseMergeVo;
import com.atguigu.gulimall.ware.vo.PurchaseDoneVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.ware.dao.PurchaseDao;
import com.atguigu.gulimall.ware.entity.PurchaseEntity;
import com.atguigu.gulimall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
    @Autowired
    private PurchaseDetailService purchaseDetailService;
    @Autowired
    private WareSkuService wareSkuService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );
        return new PageUtils(page);
    }
    @Override
    public PageUtils queryPageOfUnreceive(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>().eq("status",0).or().eq("status",1)
        );
        return new PageUtils(page);
    }
    @Override
    @Transactional
    public void puechaseMerge(PuchaseMergeVo puchaseMergeVo) {
        Long purchaseId = puchaseMergeVo.getPurchaseId();
        UpdateWrapper<PurchaseDetailEntity> wrapper = new UpdateWrapper<>();
        List<Long> items = puchaseMergeVo.getItems();
        if (purchaseId ==null){
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setCreateTime(new Date());
            purchaseEntity.setUpdateTime(new Date());
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode());
            this.save(purchaseEntity);
            wrapper.set("purchase_id",purchaseEntity.getId())
                    .set("status",WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode())
                    .in("id",items);
        }else {
            if (purchaseId !=WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()){
                throw new GulimallException(GulimallEnum.ERR_Merge_Purchase);
            }
            wrapper.set("purchase_id",purchaseId)
                    .set("status",WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode()).in("id",items);
            purchaseDetailService.update(wrapper);
        }
    }

    @Override
    @Transactional
    public void holdPurchaseMenu(List<Long> ids) {
        //根据传入的ids查询出采购单,这里明显没有跟人员关联
        List<PurchaseEntity> purchaseList = baseMapper.selectBatchIds(ids);
        //雷丰阳说你只要保留新建类型和已分配类型，我觉得只能保留已分配类型，新建类型都没分配人,我这里暂时只支持已分配的采购带领取
        //分配操作可能是上级领导做的，而领取操作可能是采购人员做的
        List<PurchaseEntity> collect = purchaseList.stream().filter((item) -> {
            if (item.getStatus() == WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()) {
                return true;
            } else {
                return false;
            }
        }).map((item) -> {
            PurchaseEntity purchaseEntity = new PurchaseEntity();
            purchaseEntity.setId(item.getId());
            purchaseEntity.setUpdateTime(new Date());
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode());
            return purchaseEntity;
        }).collect(Collectors.toList());
        updateBatchById(collect);
        //然后就是把你已领取的采购单涉及到的采购需求状态改成
        List<Long> list = collect.stream().map((item) -> {
            return item.getId();
        }).collect(Collectors.toList());
        purchaseDetailService.update(new UpdateWrapper<PurchaseDetailEntity>()
                .set("status",WareConstant.PurchaseDetailStatusEnum.BUYING.getCode())
                .in("purchase_id",list));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void done(PurchaseDoneVo vo) {
        //第一件事就是改库存，把采购需求的状态改掉
        boolean flag=true;//信号位 用于检查是否有失败的采购 但凡有一个失败采购 采购单都是异常
        List<PurChaseDetailFinish> items = vo.getItems();
        List<PurchaseDetailEntity> purchaseDetaiList = new ArrayList<>();
        for (PurChaseDetailFinish item : items) {
            //采购需求的id
            Long itemId = item.getItemId();
            Integer status = item.getStatus();
            //你前端传过来的采购需求只能是采购失败，或者完成这两个状态
            if (status !=WareConstant.PurchaseDetailStatusEnum.FINISH.getCode() && status !=WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode()){
                throw new GulimallException(GulimallEnum.ERR_FINISH_PURCHASE);
            }
            if (status==WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode()){
                //如果采购失败，不用改库存，只需要把采购需求的状态改掉
                PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
                purchaseDetailEntity.setId(itemId);
                purchaseDetailEntity.setStatus(status);
                purchaseDetaiList.add(purchaseDetailEntity);
                flag=flag&&false;
            }else {
                //采购没有失败，要改库存，要改采购需求，改状态
                //第一步改库存 先拿到采购需求
                PurchaseDetailEntity purchaseDetail = purchaseDetailService.getBaseMapper().selectById(itemId);
                Long skuId = purchaseDetail.getSkuId();
                Long wareId = purchaseDetail.getWareId();
                //如果说这是第一次采购呢？数据库都没有这条记录 wareSkuEntity肯定为空
                Integer skuNum = purchaseDetail.getSkuNum();
                //改sku库存
                wareSkuService.saveOrUpdateWareSkus(skuId,wareId,skuNum);
                //改采购需求状态
                purchaseDetail.setStatus(WareConstant.PurchaseDetailStatusEnum.FINISH.getCode());
                purchaseDetaiList.add(purchaseDetail);
                flag=flag&&true;
            }
        }
        //批量改库存，更新采购需求状态
        purchaseDetailService.updateBatchById(purchaseDetaiList);
        //改采购单状态
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(vo.getId());
        purchaseEntity.setUpdateTime(new Date());
        if (flag){
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.FINISH.getCode());
        }else {
            //但凡你前端传来的采购需求有一个失败了,我就算你这个采购单异常
            purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.HASERROR.getCode());
        }
        updateById(purchaseEntity);
    }
}